home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 January: Mac OS SDK / Dev.CD Jan 96 SDK / Dev.CD Jan 96 SDK1.toast / Development Kits (Disc 1) / QuickDraw™ GX / Programming Stuff / Sample Code / Printing Samples / Printer Drivers… / LaserWriterIIsc (New GX v1.1) / OldAPIMessageIntf.c < prev    next >
Encoding:
Text File  |  1995-04-10  |  18.6 KB  |  648 lines  |  [TEXT/MPS ]

  1. /*---------------------------------------------------------------------------
  2. FILENAME
  3.     OldAPIMessageIntf.c
  4.  
  5. DESCRIPTION
  6.     This module contains the routines which implement the old API messages
  7.     that the LaserWriter SC driver overrides.  Much of the logic in this
  8.     module was gleaned from the original LaserWriter IISC driver, and so
  9.     some of the calulations may seem a little strange.  In order to maintain
  10.     compatibility with the old driver's logic, we must preserve much of the
  11.     old logic.
  12.         
  13. COPYRIGHT
  14.      Copyright Apple Computer, Inc. 1989-1992
  15.      All rights reserved. 
  16.         
  17. INTERFACE ROUTINES:
  18.  
  19.     SD_PrValidate
  20.     SD_ConvertPrintRecordTo
  21.     SD_ConvertPrintRecordFrom
  22.  
  23. -------------------------------------------------------------------------------- */
  24.  
  25. // Include the standard Mac header files 
  26. #include "MacIncludes.h"
  27.  
  28. // Include the new QuickDraw GX graphics header files 
  29. #include <graphics routines.h>
  30. #include <graphics libraries.h>
  31. #include <math routines.h>
  32.  
  33. // Include the required Printing Manager header files 
  34. #include <PrintingManager.h>
  35. #include <PrintingMessages.h>
  36. #include <PrintingDrivers.h>
  37. #include <Collections.h>
  38. #include <Messages.h>
  39. #include <PrintingResTypes.h>
  40. #include <PrintingErrors.h>
  41.  
  42. // Include the internal driver constants and types used by this module 
  43. #include "LaserSCResources.h"
  44. #include "OldAPIMessageIntf.h"
  45.  
  46.  
  47. /***************************************************************************************
  48. *                                         INTERNAL ROUTINES                                                    *
  49. ***************************************************************************************/
  50.  
  51.  
  52. /****************************************************************************************
  53.  
  54.                             EmulatePages
  55.                             
  56.     function:
  57.                 This function takes a paper rectangle, and computes the rPage
  58.                 rectangle for it.  It uses the old LaserWriter IISC driver's page size 
  59.                 calculation "algorithm" (if it can be called such).
  60.                 
  61.     parameters:                
  62.                 hPrint        target print record whose rPage rect is updated
  63.  
  64.     returns:
  65.                 none
  66.     
  67. ****************************************************************************************/
  68. void EmulatePages(THPrint    hPrint)
  69. {
  70.     TPrInfo    *pPrInfo;
  71.     TPrStl    *pPrStl;
  72.     short        dvPaper;         // the "calculated" paper sizes
  73.     short        dhPaper;            
  74.     short        dvPage;             // the "calculated" page sizes
  75.     short        dhPage;            
  76.     short        iOneFourth;        // fudge factors which don't quite equal their names
  77.     short        iTwoFifths;        
  78.     short        iVMaxInch;        // memory limitation on the page sizes.
  79.     short        iHMaxBytes;
  80.     short        scanBits;        // the eventual # of bits across a line on the page (truncated)
  81.     short        scanLines;        // the eventual # of lines on the page (truncated)
  82.     short        iTemp;            // temporary swapping variable for landscape
  83.     short        hOff;                // used to calculated the offset paper rectangle
  84.     short        vOff;
  85.  
  86.     
  87.     pPrInfo    =    &((*hPrint)->prInfo);        
  88.     pPrStl    =    &((*hPrint)->prStl);        
  89.     
  90.  
  91.     dvPaper     =     (pPrStl->iPageV * pPrInfo->iVRes) / kMysticPaperFract;
  92.     dhPaper     =     (pPrStl->iPageH * pPrInfo->iHRes) / kMysticPaperFract;
  93.     
  94.     
  95.     // Weird fudge factors from Dave Casseres. No, I don't understand them.  No,
  96.     //    he apparently doesn't either, anymore. 
  97.         
  98.     iOneFourth    =    (pPrInfo->iHRes + 2) / 4;                // this isn't even 1/4th.
  99.     iTwoFifths    =    ((pPrInfo->iHRes << 2) + 5) / 10;    // nor is this 2/5ths!
  100.     
  101.     
  102.     // Boundary condition for large page sizes (legal > 1400 which is 11.666666667").
  103.     //    If the paper is smaller than that, then we just do the regular calculation.
  104.     //    Otherwise, we restrict the size to 12.5" on the IISC (25/2). Further, we
  105.     //    restrict the horizontal dimensions to 6.72 inches (memory limitation on 1 Mb printers
  106.         
  107.     if (pPrStl->iPageV <= 1400)
  108.     {
  109.         iVMaxInch     =     pPrStl->iPageV;
  110.         iHMaxBytes    =    kLetterRowBytes;
  111.     }
  112.     else
  113.     {
  114.         iVMaxInch     =     (25 * kMysticPaperFract) / 2;
  115.         iHMaxBytes    =    kLegalRowBytes;
  116.     }
  117.  
  118.  
  119.     // Force the horizontal dimension to fit within the laser's restrictions:
  120.     //    iHMaxBytes was just set. For letter, it's 8" (300 rowBytes). Multiply by the
  121.     //    horizontal resolution (say 72), and divide by high-resolution (300 dpi).
  122.     //    Multiply by 8 (<< 3), since we want coordinates, and the iHMaxBytes is
  123.     //    a byte count.  Always do divisions last, in order to keep precision. 
  124.     //    dhPaper is the paper size horizontally in rendering units (72 or 300). 
  125.     //    It really ought to be in one unit or the other, but in emulation mode,
  126.     //    it's in whatever the app selected.  We force the page size to fit within
  127.     //    the laser's restricted area by forcing about a 1/4" border. We do the same
  128.     //    vertically, with approximately a 2/5" border total. We truncate the results
  129.     //    (why to 16ths and to 2nds? I don't know). 
  130.     
  131.     scanBits = ((iHMaxBytes * pPrInfo->iHRes) << 3) / kHorizHighRes;
  132.     if (scanBits > (dhPaper - iOneFourth))
  133.         scanBits = dhPaper - iOneFourth;
  134.     scanBits = (scanBits >> 4) << 4;        // number of bits on a single line
  135.  
  136.  
  137.     scanLines = (iVMaxInch * pPrInfo->iVRes) / iPrPgFract;
  138.     if (scanLines > (dvPaper - iTwoFifths))
  139.         scanLines = dvPaper - iTwoFifths;
  140.     scanLines = (scanLines >> 1) << 1;        // number of lines on the page
  141.     
  142.  
  143.     // set the page size based on the orientation. Portrait uses the default
  144.     //    definitions: bits for horizontal and lines for vertical. 
  145.         
  146.     if ( TestBit((*hPrint)->prStl.wDev, kPortraitBit) )
  147.     {
  148.         dhPage = scanBits;
  149.         dvPage = scanLines;
  150.     }
  151.     else    // landscape
  152.     {
  153.         dhPage     = scanLines;
  154.         dvPage     = scanBits;
  155.         
  156.         // Reverse the meanings of paper in landscape as well. 
  157.         iTemp     = dhPaper;
  158.         dhPaper     = dvPaper;
  159.         dvPaper     = iTemp;
  160.     }
  161.  
  162.     SetRect( &(pPrInfo->rPage), 0, 0, dhPage, dvPage );
  163.  
  164.     // Create the paper size and store it in the print record 
  165.     
  166.     hOff = (dhPage - dhPaper) / 2;
  167.     vOff = (dvPage - dvPaper) / 2;
  168.     SetRect( & ((*hPrint)->rPaper) , hOff, vOff, dhPaper+hOff, dvPaper+vOff );
  169.  
  170.     // Preserve the rPaper rectangle in the printX array starting at word 5.  This is done
  171.     // to maintain compatibility with the old LaserWriter SC driver
  172.     {
  173.         BlockMove((Ptr) &((*hPrint)->rPaper), (Ptr) &((*hPrint)->printX[5]), sizeof(Rect));
  174.     }
  175. }
  176. /* EmulatePages */
  177.  
  178.  
  179. /****************************************************************************************
  180.  
  181.                             HandleZoom
  182.                             
  183.     function:
  184.                 This function handles zoom factors from PageSetup.  How does zooming work?  
  185.                 What we do is trick the application into doing the work for us by returning a 
  186.                 page size bigger than actual.  Thus when we render this into the original page
  187.                 size, we get a reduced image.
  188.                 
  189.     parameters:                
  190.                 hPrint            handle to the print record to change
  191.                 
  192.     returns:
  193.                 none
  194.     
  195. ****************************************************************************************/
  196.  
  197. void HandleZoom(THPrint    hPrint)
  198. {
  199.     gxUniversalPrintRecordPtr    pUniv;
  200.     Fixed                                zoomFactor;
  201.     Rect                                tempRect;
  202.  
  203.     // Convert print record into the universal form
  204.     SD_ConvertPrintRecordTo(hPrint);
  205.     
  206.     pUniv = (gxUniversalPrintRecordPtr) *hPrint;
  207.  
  208.     // Convert the reduction factor into a fixed zoom value 
  209.     zoomFactor = FixRatio(100, pUniv->reduction );
  210.     
  211.     // Notice that we don't zoom the device specific size, since zoom
  212.     //    factors "just" trick out the application side of things 
  213.  
  214.     tempRect = pUniv->appPage;
  215.     SetRect(&tempRect, FixRound( FixMul( (tempRect.left << 16),    zoomFactor) ), 
  216.                           FixRound( FixMul( (tempRect.top     << 16),     zoomFactor) ),
  217.                           FixRound( FixMul( (tempRect.right << 16), zoomFactor) ), 
  218.                           FixRound( FixMul( (tempRect.bottom << 16),zoomFactor) ));
  219.     pUniv->appPage = tempRect;
  220.             
  221.     tempRect = pUniv->appPaper;
  222.     SetRect(&tempRect, FixRound( FixMul( (tempRect.left << 16),    zoomFactor) ), 
  223.                           FixRound( FixMul( (tempRect.top     << 16),     zoomFactor) ),
  224.                           FixRound( FixMul( (tempRect.right << 16), zoomFactor) ), 
  225.                           FixRound( FixMul( (tempRect.bottom << 16),zoomFactor) ));
  226.     pUniv->appPaper = tempRect;
  227.         
  228.     
  229.     // Convert the print record back into the specific driver form
  230.     SD_ConvertPrintRecordFrom(hPrint);
  231. }
  232. /* HandleZoom */
  233.  
  234.  
  235. /****************************************************************************************
  236.  
  237.                             UpdatePrInfoPt
  238.                             
  239.     function:
  240.                 This function updates the prInfoPT portion of the print record.  The logic
  241.                 for updating the prInfoPT structure comes from the original LaserWriter
  242.                 SC driver.
  243.                 
  244.     parameters:                
  245.                 hPrint                handle to the print record to change
  246.                 calcDeviceRects    true to calc device rectangles
  247.                 
  248.     returns:
  249.                 none
  250.     
  251. ****************************************************************************************/
  252. void UpdatePrInfoPt(THPrint hPrint, Boolean calcDeviceRects)
  253. {
  254.     Rect        tempRect;
  255.     TPPrint    pPrint = *hPrint;
  256.     short        precFlags;
  257.     
  258.     // Initially assume the prInfoPT structure will be like that of prInfo
  259.     
  260.     pPrint->prInfoPT.iHRes = pPrint->prInfo.iHRes;
  261.     pPrint->prInfoPT.iVRes = pPrint->prInfo.iVRes;
  262.     pPrint->prInfoPT.rPage = pPrint->prInfo.rPage;
  263.     
  264.     precFlags = pPrint->prXInfo.iBandV;
  265.     
  266.     if (
  267.         (calcDeviceRects) && 
  268.         ( !TestBit(precFlags, kDevResBit) )    //    T => We're not imaging at device resolution
  269.         )
  270.     {
  271.         short        theRes = pPrint->prInfoPT.iHRes;
  272.         Fixed        scale;
  273.  
  274.     
  275.         // Compute the new resolution based upon the scaling factors
  276.         
  277.         if ( TestBit(precFlags, kScale75Bit) )
  278.         {
  279.             theRes = (theRes << 2) / 3;
  280.         }
  281.         else 
  282.         if ( TestBit(precFlags, kScale50Bit) )
  283.         {
  284.             theRes <<= 1;
  285.         }
  286.         else 
  287.         if ( TestBit(precFlags, kScale25Bit) )
  288.             theRes <<= 2;
  289.             
  290.         // Are we doing exact bitmap scaling, or scaling to the resolution of the device?
  291.         
  292.         if ( TestBit(precFlags, kExactBitBit) )
  293.             {
  294.             scale = FixRatio(kHorizHighExactRes, theRes);
  295.             theRes = kHorizHighExactRes;
  296.             }
  297.         else
  298.             {
  299.             scale = FixRatio(kHorizHighRes, theRes);
  300.             theRes = kHorizHighRes;
  301.             }
  302.             
  303.         // Update the resolution fields
  304.         
  305.         pPrint->prInfoPT.iHRes = theRes;
  306.         pPrint->prInfoPT.iVRes = theRes;        // the old driver doesn't update the iVRes field, but we will
  307.  
  308.         // Now we need to calculate the new rPage
  309.         tempRect =  pPrint->prInfoPT.rPage;
  310.     
  311.         // Calculate the device resolution rectangle
  312.         SetRect(&tempRect, FixRound( FixMul( (tempRect.left << 16),    scale) ), 
  313.                               FixRound( FixMul( (tempRect.top     << 16), scale) ),
  314.                               FixRound( FixMul( (tempRect.right << 16), scale) ), 
  315.                               FixRound( FixMul( (tempRect.bottom << 16), scale) ));
  316.     
  317.         // Store away the device page size
  318.         (*hPrint)->prInfoPT.rPage = tempRect;
  319.     }
  320.  
  321. }
  322. /* UpdatePrInfoPt */
  323.  
  324.  
  325.  
  326. /****************************************************************************************
  327.  
  328.                             UpdatePrintRecord
  329.                             
  330.     function:
  331.                 This function updates the print record based upon the application's
  332.                 calls to PrGeneral.
  333.                 
  334.     parameters:                
  335.                 hPrint                print record to update
  336.                 calcDeviceRects    true to calculate device rectangles, false to copy from apps
  337.  
  338.     returns:
  339.                 none
  340.     
  341. ****************************************************************************************/
  342. void UpdatePrintRecord(THPrint hPrint, Boolean calcDeviceRects)
  343. {
  344.     // emulate those crazy old style pages        
  345.     EmulatePages(hPrint);
  346.  
  347.     // Handle the case of zoom factors by scaling the rectangles
  348.     HandleZoom(hPrint);
  349.  
  350.     // Compute and fill in the devPage rectangle and the remainder of prInfoPT
  351.     UpdatePrInfoPt(hPrint, calcDeviceRects);
  352. }
  353. /* UpdatePrintRecord */
  354.  
  355.  
  356.  
  357. /***************************************************************************************
  358. *                                         INTERFACE ROUTINES                                                     *
  359. ***************************************************************************************/
  360.  
  361. /****************************************************************************************
  362.  
  363.                             SD_PrValidate
  364.                             
  365.     function:
  366.                 This function validates the print record.  If the passed-in print record contains
  367.                 valid information (see below), then it's updated based upon the application's
  368.                 calls to Prgeneral.  Otherwise, it is unchanged, and the return code is true.
  369.                 Otherwise, the print record is defaulted (with SD_PrintDefault), and the 
  370.                 return value is false.
  371.                 
  372.                 Validation:
  373.                     The upper byte of the wDev must be the ID of the device 
  374.                         (kPrinterID in Resources.h).
  375.                     The version of the print record must be current
  376.                         (oldLWSCPrintRecordVersion in Resources.h)
  377.                     (For new print records, we will validate all of the fields which are 
  378.                      public (e.g., paper size), not just these fields)
  379.                 
  380.     parameters:                
  381.                 hPrint                    print record to validate
  382.                 wasChanged                returns true if print record was invalid; false otherwise
  383.                 
  384.     returns:
  385.                 OSErr
  386.     
  387. ****************************************************************************************/
  388. OSErr SD_PrValidate(THPrint hPrint, Boolean *wasChanged)
  389. {
  390.     short        wDev;                        // device specific stuff in this word
  391.     Boolean    returnVal = true;        // initialize return value to "invalid"
  392.                                             //     Why is true == "invalid"? Nobody knows!
  393.     
  394.     // check the wDev.  The upper byte must be equal to kPrinterID.  We get the
  395.     //  wDev, and shift wDev DOWN eight.
  396.         
  397.     wDev =  (*hPrint)->prStl.wDev;
  398.     wDev >>= 8;                                // get just the device ID
  399.  
  400.  
  401.     // If the device id is equal, then check the version number of the print record.
  402.     //    Only if that is also equal to the current version, will we return false (valid).
  403.         
  404.     if (wDev == kPrinterID)
  405.         if ( ((*hPrint)->iPrVersion) == oldLWSCPrintRecordVersion )
  406.             returnVal = false;
  407.             
  408.  
  409.     // If the print record is not valid, then return the default print record.
  410.     // Otherwise, update the print record, based on the application's calls
  411.     // to PrGeneral.
  412.  
  413.     if (returnVal)
  414.         PrintDefault(hPrint);
  415.     else
  416.         UpdatePrintRecord(hPrint, false);
  417.         
  418.     *wasChanged = returnVal;
  419.     
  420.     return(noErr);
  421. }
  422. /* SD_PrValidate */
  423.  
  424.  
  425. /****************************************************************************************
  426.  
  427.                             SD_OpenDoc
  428.                             
  429.     function:     
  430.                 SD_OpenDoc is the first call for printing an old style document.  
  431.                 
  432.     
  433. ****************************************************************************************/
  434. OSErr SD_OpenDoc(    THPrint hPrint,                // old-style print record for this document
  435.                             TPPrPort *printingPort)
  436. {
  437.     OSErr    anErr;
  438.     
  439.     UpdatePrintRecord(hPrint, true);
  440.  
  441.     anErr = Forward_GXPrOpenDoc(hPrint, printingPort);
  442.     
  443.     return(anErr);
  444.     
  445. } /* SD_OpenDoc */
  446.  
  447. /****************************************************************************************
  448.  
  449.                             SD_ConvertPrintRecordTo
  450.                             
  451.     function:     
  452.                 SD_ConvertPrintRecordTo converts the fields of the print record for
  453.                 the device into the universal print record format.  
  454.                 
  455.     parameters:    
  456.                 hPrint        print record to convert to universal format
  457.     
  458.     returns:
  459.                 OSErr
  460.     
  461. ****************************************************************************************/
  462. OSErr SD_ConvertPrintRecordTo(THPrint hPrint)
  463. {
  464.     gxUniversalPrintRecordPtr    pUniv;
  465.     TPPrint                             pPrint;
  466.     short                                options = 0;
  467.     short                                oldFlags;
  468.  
  469.     pUniv = (gxUniversalPrintRecordPtr) *hPrint;
  470.     pPrint = *hPrint;
  471.     
  472.     // Convert paper feed settings (old and univ setting are switched)
  473.  
  474.     if ( pPrint->prStl.feed == oldPRECAutoFeed )
  475.         pUniv->feed = gxAutoFeed;
  476.     else
  477.         pUniv->feed = gxManualFeed;
  478.     
  479.     // Determine the new options field settings; univ and specific share this location
  480.  
  481.     oldFlags = pPrint->prXInfo.iBandV;
  482.  
  483.     if ( TestBit(oldFlags, kTextSmoothingBit) )
  484.         options |= gxTextSmoothing;
  485.         
  486.     if ( TestBit(oldFlags, kExactBitBit) )
  487.         options |= gxPreciseBitmap;
  488.         
  489.     if ( TestBit(oldFlags, kDevResBit) )
  490.         pUniv->appHRes = pUniv->appVRes = 300;
  491.     else
  492.         pUniv->appHRes = pUniv->appVRes = 72;
  493.         
  494.     pUniv->options = options;
  495.  
  496.     // We need to save the settings of the other flag bits from the old print record (e.g. fGrayScale,
  497.     // fDraftBits, etc.).  We save them in printX[18].
  498.     pUniv->printX[18] = oldFlags;
  499.     
  500.     // Now determine the scaling factor, if any, and designate the proper dialog button that
  501.     // corresponds to the scaling factor.  The userCluster1 field specifies the dialog button.
  502.     
  503.     if ( TestBit(oldFlags, kScale75Bit) )
  504.     {
  505.         pUniv->reduction = 75;
  506.         pUniv->userCluster1 = 1;
  507.     }
  508.     else 
  509.     if ( TestBit(oldFlags, kScale50Bit) )
  510.     {
  511.         pUniv->reduction = 50;
  512.         pUniv->userCluster1 = 2;
  513.     }
  514.     else 
  515.     if ( TestBit(oldFlags, kScale25Bit) )
  516.     {
  517.         pUniv->reduction = 25;
  518.         pUniv->userCluster1 = 3;
  519.     }
  520.     else     //    T => No scaling being performed
  521.     {
  522.         pUniv->reduction = 100;
  523.         pUniv->userCluster1 = 0;
  524.     }
  525.  
  526.     // Set the orientation properly
  527.  
  528.     if ( TestBit(pPrint->prStl.wDev, kPortraitBit) )
  529.         pUniv->orientation = gxPortraitOrientation;
  530.     else
  531.         pUniv->orientation = gxLandscapeOrientation;
  532.         
  533.     // Always assign these fields explicit values to ensure they don't cause problems
  534.     
  535.     pUniv->qualityMode     = gxBestQuality;
  536.     pUniv->firstTray         = gxFirstTray;
  537.     pUniv->remainingTray    = gxFirstTray;
  538.     pUniv->coverPage         = gxNoCoverPage;
  539.     pUniv->headMotion     = gxUnidirectionalMotion;
  540.     pUniv->saveFile         = gxNoFile;
  541.     
  542.     return(noErr);
  543. }
  544. /* SD_ConvertPrintRecordTo */
  545.  
  546.  
  547. /****************************************************************************************
  548.  
  549.                             SD_ConvertPrintRecordFrom
  550.                             
  551.     function:     
  552.                 SD_ConvertPrintRecordFrom converts the fields of the print record in 
  553.                 universal print record format into the print record format for the
  554.                 specific device. 
  555.                 
  556.     parameters:    
  557.                 hPrint        print record to convert to device specific format
  558.     
  559.     returns:
  560.                 OSErr
  561.     
  562. ****************************************************************************************/
  563. OSErr SD_ConvertPrintRecordFrom(THPrint hPrint)
  564. {
  565.     gxUniversalPrintRecordPtr    pUniv;
  566.     TPPrint                             pPrint;
  567.     short                                iBandV = 0;
  568.     short                                oldOptions;
  569.     short                                savedOldFlags;
  570.  
  571.     pUniv = (gxUniversalPrintRecordPtr) *hPrint;
  572.     pPrint = *hPrint;
  573.     
  574.     // Set the orientation properly
  575.  
  576.     if (pUniv->orientation == gxPortraitOrientation)
  577.         pPrint->prStl.wDev |= kPortraitBit;
  578.     else
  579.         pPrint->prStl.wDev &= ~kPortraitBit;
  580.  
  581.     // Convert paper feed settings (old and univ setting are switched)
  582.  
  583.     if ( pUniv->feed == gxAutoFeed )
  584.         pPrint->prStl.feed = oldPRECAutoFeed;
  585.     else
  586.         pPrint->prStl.feed = oldPRECManualFeed;
  587.  
  588.     // Set the flags in the iBandV field of the print record
  589.  
  590.     oldOptions = pUniv->options;
  591.     
  592.     if ( TestBit(oldOptions, gxTextSmoothing) )
  593.         iBandV |= kTextSmoothingBit;
  594.         
  595.     switch( pUniv->userCluster1 )    //    Based on the scaling dialog button setting, set the scaling factor
  596.     {
  597.         case 0:
  598.             break;
  599.             
  600.         case 1:
  601.             iBandV |= kScale75Bit;
  602.             break;
  603.             
  604.         case 2:
  605.             iBandV |= kScale50Bit;
  606.             break;
  607.             
  608.         case 3:
  609.             iBandV |= kScale25Bit;
  610.             break;
  611.     }
  612.     
  613.     if ( TestBit(oldOptions, gxPreciseBitmap) )
  614.         iBandV |= kExactBitBit;
  615.  
  616.     savedOldFlags = pUniv->printX[18];
  617.     
  618.     if (pUniv->appHRes != 72)
  619.         iBandV |= kDevResBit;
  620.  
  621.     if ( TestBit(savedOldFlags, kDraftBitsBit) )
  622.         iBandV |= kDraftBitsBit;
  623.  
  624.     if ( TestBit(savedOldFlags, kAbortChkBit) )
  625.         iBandV |= kAbortChkBit;
  626.  
  627.     if ( TestBit(savedOldFlags, kGrayScaleBit) )
  628.         iBandV |= kGrayScaleBit;
  629.  
  630.     // Initialize the remaining fields in the TPrXInfo structure
  631.     
  632.     pPrint->prXInfo.iBandV = iBandV;
  633.     pPrint->prXInfo.iBandH = 0;
  634.     pPrint->prXInfo.iDevBytes = 0;
  635.     pPrint->prXInfo.iBands = 0;
  636.     pPrint->prXInfo.bPatScale = kPatScale;
  637.     pPrint->prXInfo.bUlThick = 0;
  638.     pPrint->prXInfo.bUlOffset = 0;
  639.     pPrint->prXInfo.bUlShadow = 0;
  640.     pPrint->prXInfo.scan = scanTB;
  641.     pPrint->prXInfo.bXInfoX = 0;
  642.  
  643.     pPrint->printX[18] = 0;
  644.  
  645.     return(noErr);
  646. }
  647. /* SD_ConvertPrintRecordFrom */
  648.